package com.sdsmdg.harjot.materialshadows;

import static com.sdsmdg.harjot.materialshadows.Constants.*;

import com.sdsmdg.harjot.materialshadows.shadowutils.ShadowGenerator;

import ohos.app.Context;
import ohos.agp.components.AttrSet;
import ohos.agp.components.ComponentContainer;
import ohos.agp.components.DependentLayout;

public class MaterialShadowViewWrapper extends DependentLayout implements ComponentContainer.ArrangeListener {
    private float offsetX = DEFAULT_X_OFFSET;
    private float offsetY = DEFAULT_Y_OFFSET;

    private float mshadowAlpha = DEFAULT_SHADOW_ALPHA;

    private boolean mshouldShowWhenAllReady = DEFAULT_SHOW_WHEN_ALL_READY;
    private boolean mshouldCalculateAsync = DEFAULT_CALCULATE_ASYNC;
    private boolean mshouldAnimateShadow = DEFAULT_ANIMATE_SHADOW;

    private int manimationDuration = DEFAULT_ANIMATION_TIME;

    private ShadowGenerator shadowGenerator;

    /**
     * MaterialShadowViewWrapper
     *
     * @param context 上下文
     **/
    public MaterialShadowViewWrapper(Context context) {
        super(context);
    }

    /**
     * MaterialShadowViewWrapper
     *
     * @param context 上下文
     * @param attrs 属性集
     **/
    public MaterialShadowViewWrapper(Context context, AttrSet attrs) {
        super(context, attrs);
        initXMLAttrs(context, attrs);
    }

    /**
     * MaterialShadowViewWrapper
     *
     * @param context 上下文
     * @param attrs 属性集
     * @param defStyleAttr 样式属性
     **/
    public MaterialShadowViewWrapper(Context context, AttrSet attrs, String defStyleAttr) {
        super(context, attrs, defStyleAttr);
        initXMLAttrs(context, attrs);
    }

    void initXMLAttrs(Context context, AttrSet attrs) {
        setArrangeListener(this);
        setClipEnabled(false);

        if (attrs != null) {
            if (attrs.getAttr("shadowAlpha").isPresent()) {
                mshadowAlpha = attrs.getAttr("shadowAlpha").get().getFloatValue();
            }
            if (attrs.getAttr("shadowOffsetX").isPresent()) {
                offsetX = attrs.getAttr("shadowOffsetX").get().getFloatValue();
            }
            if (attrs.getAttr("shadowOffsetY").isPresent()) {
                offsetY = attrs.getAttr("shadowOffsetY").get().getFloatValue();
            }
            if (attrs.getAttr("calculateAsync").isPresent()) {
                mshouldCalculateAsync = attrs.getAttr("calculateAsync").get().getBoolValue();
            }
            if (attrs.getAttr("animateShadow").isPresent()) {
                mshouldAnimateShadow = attrs.getAttr("animateShadow").get().getBoolValue();
            }
            if (attrs.getAttr("showWhenAllReady").isPresent()) {
                mshouldShowWhenAllReady = attrs.getAttr("showWhenAllReady").get().getBoolValue();
            }
            if (attrs.getAttr("animationDuration").isPresent()) {
                manimationDuration = attrs.getAttr("animationDuration").get().getIntegerValue();
            }
        }
    }

    @Override
    public boolean onArrange(int left, int top, int width, int height) {
        if (shadowGenerator == null) {
            shadowGenerator = new ShadowGenerator(this, offsetX, offsetY, mshadowAlpha,
                    mshouldShowWhenAllReady, mshouldCalculateAsync,
                    mshouldAnimateShadow, manimationDuration);
        }
        shadowGenerator.generate();
        return false;
    }

    public float getOffsetX() {
        return offsetX;
    }

    /**
     * 设置X轴偏移量
     *
     * @param offsetX 偏移量
     **/
    public void setOffsetX(float offsetX) {
        this.offsetX = offsetX;
        if (shadowGenerator != null) {
            shadowGenerator.setOffsetX(offsetX);
        }
    }

    public float getOffsetY() {
        return offsetY;
    }

    /**
     * 设置Y轴偏移量
     *
     * @param offsetY 偏移量
     **/
    public void setOffsetY(float offsetY) {
        this.offsetY = offsetY;
        if (shadowGenerator != null) {
            shadowGenerator.setOffsetY(offsetY);
        }
    }

    public float getShadowAlpha() {
        return mshadowAlpha;
    }

    /**
     * 设置阴影透明度
     *
     * @param shadowAlpha 透明度
     **/
    public void setShadowAlpha(float shadowAlpha) {
        this.mshadowAlpha = shadowAlpha;
        if (shadowGenerator != null) {
            shadowGenerator.setShadowAlpha(shadowAlpha);
        }
    }

    /**
     * 设置阴影动画
     *
     * @param shouldAnimateShadow 动画
     **/
    public void setShouldAnimateShadow(boolean shouldAnimateShadow) {
        this.mshouldAnimateShadow = shouldAnimateShadow;
        if (shadowGenerator != null) {
            shadowGenerator.setShouldAnimateShadow(shouldAnimateShadow);
        }
    }

    /**
     * 阴影动画
     *
     * @return shouldAnimateShadow 阴影动画
     **/
    public boolean shouldAnimateShadow() {
        return mshouldAnimateShadow;
    }

    /**
     * 设置计算异步
     *
     * @param shouldCalculateAsync 异步
     **/
    public void setShouldCalculateAsync(boolean shouldCalculateAsync) {
        this.mshouldCalculateAsync = shouldCalculateAsync;
        if (shadowGenerator != null) {
            shadowGenerator.setShouldCalculateAsync(shouldCalculateAsync);
        }
    }

    /**
     * 计算异步
     *
     * @return shouldCalculateAsync 异步
     **/
    public boolean shouldCalculateAsync() {
        return mshouldCalculateAsync;
    }

    /**
     * 设置“准备就绪时显示阴影”
     *
     * @param shouldWaitForAllReady 布尔类型
     **/
    public void setShowShadowsWhenAllReady(boolean shouldWaitForAllReady) {
        this.mshouldShowWhenAllReady = shouldWaitForAllReady;
        if (shadowGenerator != null) {
            shadowGenerator.setShouldShowWhenAllReady(shouldWaitForAllReady);
        }
    }

    /**
     * 是否准备就绪时显示阴影
     *
     * @return shouldShowWhenAllReady准备就绪
     **/
    public boolean shouldWaitForAllReady() {
        return mshouldShowWhenAllReady;
    }

    public int getAnimationDuration() {
        return manimationDuration;
    }

    /**
     * 设置动画时间
     *
     * @param animationDuration 动画时间
     **/
    public void setAnimationDuration(int animationDuration) {
        this.manimationDuration = animationDuration;
        if (shadowGenerator != null) {
            shadowGenerator.setAnimationDuration(animationDuration);
        }
    }
}
